package com.silence.springboot.service.impl;


import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.silence.springboot.dto.UserRoleJoinRoleDto;
import com.silence.springboot.constants.StringConstants;
import com.silence.springboot.convert.LoginAdminConvert;
import com.silence.springboot.convert.UserBaseInfoConvert;
import com.silence.springboot.dao.LoginAdminDao;
import com.silence.springboot.dao.UserBaseInfoDao;
import com.silence.springboot.dao.UserRoleDao;
import com.silence.springboot.entity.LoginAdminEntity;
import com.silence.springboot.entity.UserBaseInfoEntity;
import com.silence.springboot.enums.ResultCode;
import com.silence.springboot.exception.ApiException;
import com.silence.springboot.mapper.UserBaseInfoMapper;
import com.silence.springboot.service.UserBaseInfoService;
import com.silence.springboot.utils.EncryptionDecryptionUtil;
import com.silence.springboot.utils.JwtUtil;
import com.silence.springboot.vo.input.AdminAddUserBaseInfoInput;
import com.silence.springboot.vo.input.AdminUpdateUserBaseInfoInput;
import com.silence.springboot.vo.input.SearchByConditionInput;
import com.silence.springboot.vo.output.PageOutput;
import com.silence.springboot.vo.output.QueryUserBaseInfoByTokenOutput;
import com.silence.springboot.vo.output.SearchByConditionOutput;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户基础信息表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserBaseInfoServiceImpl extends ServiceImpl<UserBaseInfoMapper, UserBaseInfoEntity> implements UserBaseInfoService {

    /**
     * 用户基础信息表 数据访问层接口
     */
    private final UserBaseInfoDao userBaseInfoDao;

    /**
     * 登录系统表 数据访问层接口
     */
    private final LoginAdminDao loginAdminDao;

    /**
     * 用户基础信息表 转换器接口
     */
    private final UserBaseInfoConvert userBaseInfoConvert;

    /**
     * 登录系统入参转换
     */
    private final LoginAdminConvert loginAdminConvert;

    /**
     * 用户角色关联表 数据访问层接口
     */
    private final UserRoleDao userRoleDao;

    /**
     * 根据token查询用户信息
     *
     * @param token token
     * @return 用户信息
     */
    @Override
    public QueryUserBaseInfoByTokenOutput queryUserBaseInfoByToken(String token) {
        log.info("请求头中的 token 为：{}", token);
        // 解析 token
        Long loginId = JwtUtil.getUserId(token);
        // 查询用户信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoDao.queryUserBaseInfoByUserId(loginId);
        if (Objects.isNull(userBaseInfoEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_TOKEN_ERROR);
        }
        // 返回用户信息
        return userBaseInfoConvert.toQueryUserBaseInfoByTokenOutput(userBaseInfoEntity);
    }

    /**
     * 分页查询用户基础信息
     *
     * @param pageNum  页码
     * @param pageSize 每页数量
     * @return 用户基础信息
     */
    @Override
    public Page<PageOutput> page(Integer pageNum, Integer pageSize) {
        Page<PageOutput> outputPage = new Page<>();
        // 分页查询
        Page<UserBaseInfoEntity> page = userBaseInfoDao.page(pageNum, pageSize);
        if (Objects.isNull(page)) {
            return outputPage;
        }
        List<UserBaseInfoEntity> pageList = page.getRecords();
        if (CollectionUtils.isEmpty(pageList)) {
            return outputPage;
        }
        // 查询用户角色关联表
        List<Long> userIdList = pageList.stream().map(UserBaseInfoEntity::getId).toList();
        Map<String, List<UserRoleJoinRoleDto>> userRoleMap = userRoleDao.selectUserRoleJoinRole(userIdList).stream()
                .collect(Collectors.groupingBy(UserRoleJoinRoleDto::getUserId));
        // 转换返回值
        List<PageOutput> list = pageList.stream().map(userBaseInfoConvert::toPageOutput).toList();
        list.forEach(pageOutput -> {
            List<UserRoleJoinRoleDto> userRoleJoinRoleDtoList = userRoleMap.get(pageOutput.getId());
            if (CollectionUtils.isNotEmpty(userRoleJoinRoleDtoList)) {
                pageOutput.setUserRoleJoinRoleDtoList(userRoleJoinRoleDtoList);
            } else {
                pageOutput.setUserRoleJoinRoleDtoList(Collections.emptyList());
            }
        });
        // 返回分页数据
        outputPage.setRecords(list);
        outputPage.setPageNumber(page.getPageNumber());
        outputPage.setPageSize(page.getPageSize());
        outputPage.setTotalPage(page.getTotalPage());
        outputPage.setTotalRow(page.getTotalRow());
        return outputPage;
    }

    /**
     * 新增用户基础信息
     *
     * @param input 用户基础信息输入类
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void adminAddUserBaseInfo(AdminAddUserBaseInfoInput input) {
        LoginAdminEntity selectAdminEntity = loginAdminDao.selectOneByQuery(input.getUsername());
        if (Objects.nonNull(selectAdminEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_USERNAME_EXIST);
        }
        // 密码加密
        String password = input.getPassword();
        String sha256Str = EncryptionDecryptionUtil.getSha256Str(StringConstants.KEY.concat(password));
        input.setPassword(sha256Str);
        input.setAvatar(StringConstants.DEFAULT_AVATAR);
        // 新增用户基础信息
        LoginAdminEntity loginAdminEntity = loginAdminConvert.AdminAddUserBaseInfoInputToLoginAdminEntity(input);
        loginAdminDao.insert(loginAdminEntity);
        // 获取登录id
        LoginAdminEntity databaseEntity = loginAdminDao.selectOneByQuery(input.getUsername());
        if (Objects.isNull(databaseEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
        }
        Long loginId = databaseEntity.getId();
        // 新增用户基础信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoConvert.adminAddUserBaseInfoInputToUserBaseInfoEntity(input);
        userBaseInfoEntity.setLoginId(loginId);
        boolean insertFlag = userBaseInfoDao.insertOrUpdate(userBaseInfoEntity);
        if (!insertFlag) {
            throw new ApiException(ResultCode.USER_BASE_INFO_INSERT_ERROR);
        }
        log.info("新增用户基础信息成功");
    }

    /**
     * 修改用户基础信息
     *
     * @param input 用户基础信息输入类
     */
    @Override
    public void adminUpdateUserBaseInfo(AdminUpdateUserBaseInfoInput input) {
        // 修改用户基础信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoConvert.adminUpdateUserBaseInfoInputToUserBaseInfoEntity(input);
        boolean updateFlag = userBaseInfoDao.insertOrUpdate(userBaseInfoEntity);
        if (!updateFlag) {
            throw new ApiException(ResultCode.USER_BASE_INFO_UPDATE_ERROR);
        }
        log.info("修改用户基础信息成功，用户id为：{}", input.getId());
    }

    /**
     * 删除用户基础信息
     *
     * @param id 用户基础信息id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        // 查询用户基础信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoDao.selectOneById(id);
        if (Objects.isNull(userBaseInfoEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
        }
        // 删除用户基础信息
        userBaseInfoDao.deleteById(id);
        // 删除登录系统表
        loginAdminDao.deleteById(userBaseInfoEntity.getLoginId());
        log.info("删除用户基础信息成功，用户id为：{}", id);
    }

    /**
     * 批量删除用户基础信息
     *
     * @param ids 用户基础信息id列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchByIds(List<Long> ids) {
        // 查询用户基础信息
        List<UserBaseInfoEntity> userBaseInfoEntityList = userBaseInfoDao.selectListByIds(ids);
        // 删除用户基础信息
        List<Long> loginIdList = userBaseInfoEntityList.stream().map(UserBaseInfoEntity::getLoginId).toList();
        loginAdminDao.deleteBatchByIds(loginIdList);
        // 删除登录系统表
        userBaseInfoDao.deleteBatchByIds(ids);
    }

    /**
     * 根据条件查询用户基础信息
     *
     * @param input 用户基础信息输入类
     * @return 用户基础信息列表
     */
    @Override
    public Page<SearchByConditionOutput> searchByCondition(SearchByConditionInput input) {
        Page<SearchByConditionOutput> outputPage = new Page<>();
        // 转换查询条件
        UserBaseInfoEntity convertEntity = userBaseInfoConvert.searchByConditionInputToUserBaseInfoEntity(input);
        // 查询用户基础信息
        Page<UserBaseInfoEntity> page = userBaseInfoDao.selectListByQuery(input.getPageNum(), input.getPageSize(), convertEntity);
        // 查询用户角色关联表
        List<Long> userIdList = page.getRecords().stream().map(UserBaseInfoEntity::getId).toList();
        Map<String, List<UserRoleJoinRoleDto>> userRoleMap = userRoleDao.selectUserRoleJoinRole(userIdList).stream()
                .collect(Collectors.groupingBy(UserRoleJoinRoleDto::getUserId));
        // 转换返回值
        List<SearchByConditionOutput> outputList = page.getRecords().stream().map(userBaseInfoConvert::toSearchByConditionOutput).toList();
        outputList.forEach(item -> {
            List<UserRoleJoinRoleDto> userRoleJoinRoleDtoList = userRoleMap.get(item.getId());
            if (CollectionUtils.isNotEmpty(userRoleJoinRoleDtoList)) {
                item.setUserRoleList(userRoleJoinRoleDtoList);
            } else {
                item.setUserRoleList(Collections.emptyList());
            }
        });
        // 返回分页数据
        outputPage.setRecords(outputList);
        outputPage.setPageNumber(page.getPageNumber());
        outputPage.setPageSize(page.getPageSize());
        outputPage.setTotalPage(page.getTotalPage());
        outputPage.setTotalRow(page.getTotalRow());
        return outputPage;
    }
}